package com.kamistoat.meimeichat.meimeichatclient.socket.handlers;

import com.alibaba.fastjson.JSON;
import com.kamistoat.meimeichat.meimeichatclient.application.UIServiceConnector;
import com.kamistoat.meimeichat.meimeichatclient.config.NettyClientConstant;
import com.kamistoat.meimeichat.meimeichatclient.infrastructure.util.BeanUtil;
import com.kamistoat.meimeichat.meimeichatclient.infrastructure.util.CacheUtil;
import com.kamistoat.meimeichat.meimeichatclient.socket.NettyClientBizHandler;
import com.kamistoat.meimeichat.meimeichatui.view.chat.IChatMethod;
import com.kamistoat.meimeichatserveraggrement.protocol.Command;
import com.kamistoat.meimeichatserveraggrement.protocol.login.LoginResponse;
import com.kamistoat.meimeichatserveraggrement.protocol.login.dto.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.socket.DatagramPacket;
import javafx.application.Platform;
import sun.misc.Cache;

import java.net.InetSocketAddress;
import java.util.List;

/**
 * 客户端处理服务器返回的 登录响应
 */
public class LoginHandler extends NettyClientBizHandler<LoginResponse> {

    public LoginHandler(UIServiceConnector uiServiceConnector) {
        super(uiServiceConnector);
    }

    /**
     * @param channel
     * @param msg
     * @Warning:子类只需要重写该方法
     */
    @Override
    public void channelRead(Channel channel, LoginResponse msg) {
        if (!msg.isSuccess()) {
            System.out.println("用户名或密码错误，登录失败");
            return;
        }

        CacheUtil.userId = msg.getUserId();
        CacheUtil.userNickname = msg.getUserNickName();
        CacheUtil.userHead = msg.getUserHead();

        // 清空之前的缓存
        CacheUtil.p2pMap.clear();
        CacheUtil.p2pDateMap.clear();
        CacheUtil.p2pFailureDateMap.clear();

        // 登录成功，则向服务端发送一个UDP链接，内容就是该Client的userId，以便让服务端记录该Client的P2P地址
        logger.info("登录成功，向服务端传递P2P地址...");
        Channel clientP2PChannel = BeanUtil.getBean("ClientP2PChannel", Channel.class);
        byte[] userIdBytes = CacheUtil.userId.getBytes();
        ByteBuf userIdByteBuf = Unpooled.buffer();
        // 添加数据长度，占4位. 加1是因为存在首位的标识符
        userIdByteBuf.writeInt(userIdBytes.length + 1);
        // 添加首位标识，标识消息类型
        userIdByteBuf.writeByte(Command.UDP_ClientOnlineNotice);
        userIdByteBuf.writeBytes(userIdBytes);
        // ByteBuf userIdByteBuf = Unpooled.copiedBuffer(CacheUtil.userId.getBytes());
        clientP2PChannel.writeAndFlush(
                new DatagramPacket(userIdByteBuf,
                        new InetSocketAddress(NettyClientConstant.NETTY_SERVER_P2P_HOST, NettyClientConstant.NETTY_SERVER_P2P_PORT)));

        logger.info("更新Client窗口...");
        Platform.runLater(() -> {
            uiServiceConnector.getILoginMethod().doLoginSuccess();
            IChatMethod chat = uiServiceConnector.getIChatMethod();
            // 设置用户信息
            chat.setUserInfo(msg.getUserId(), msg.getUserNickName(), msg.getUserHead());
            // 对话框
            List<ChatTalkDto> chatTalkList = msg.getChatTalkList();
            if (null != chatTalkList && chatTalkList.size() > 0) {
                chatTalkList.forEach(talk -> {
                            chat.addTalkBox(0, talk.getTalkType(), talk.getTalkId(), talk.getTalkName(), talk.getTalkHead(), talk.getTalkSketch(), talk.getTalkDate(), true);
                            CacheUtil.talkMap.put(talk.getTalkId(), 1);
                            switch (talk.getTalkType()) {
                                // 好友
                                case 0:
                                    List<ChatRecordDto> userRecordList = talk.getChatRecordList();
                                    if (null == userRecordList || userRecordList.isEmpty()) return;
                                    for (int i = userRecordList.size() - 1; i >= 0; i--) {
                                        ChatRecordDto chatRecord = userRecordList.get(i);
                                        //  自己的消息
                                        if (0 == chatRecord.getMsgUserType()) {
                                            chat.addTalkMsgRight(chatRecord.getTalkId(), chatRecord.getMsgContent(), chatRecord.getMsgType(), chatRecord.getMsgDate(), true, false, false);
                                            continue;
                                        }
                                        // 好友的消息
                                        if (1 == chatRecord.getMsgUserType()) {
                                            chat.addTalkMsgUserLeft(chatRecord.getTalkId(), talk.getTalkName(), talk.getTalkHead(), chatRecord.getMsgContent(), chatRecord.getMsgType(), chatRecord.getMsgDate(), true, false, false);
                                        }
                                    }
                                    break;
                                // 群组
                                case 1:
                                    List<ChatRecordDto> groupRecordList = talk.getChatRecordList();
                                    if (null == groupRecordList || groupRecordList.isEmpty()) return;
                                    for (int i = groupRecordList.size() - 1; i >= 0; i--) {
                                        ChatRecordDto chatRecord = groupRecordList.get(i);
                                        //  自己的消息
                                        if (0 == chatRecord.getMsgUserType()) {
                                            chat.addTalkMsgRight(chatRecord.getTalkId(), chatRecord.getMsgContent(), chatRecord.getMsgType(), chatRecord.getMsgDate(), true, false, false);
                                            continue;
                                        }
                                        // 他人的消息
                                        if (1 == chatRecord.getMsgUserType()) {
                                            chat.addTalkMsgGroupLeft(chatRecord.getTalkId(), chatRecord.getSenderId(), chatRecord.getSenderNickName(), chatRecord.getSenderHead(), chatRecord.getMsgContent(), chatRecord.getMsgType(), chatRecord.getMsgDate(), true, false, false);
                                        }
                                    }
                                    break;
                                default:
                                    break;
                            }

                        }
                );

            }
            // 群组
            List<GroupsDto> groupsList = msg.getGroupsList();
            if (null != groupsList && groupsList.size() > 0) {
                groupsList.forEach(groups -> chat.addFriendGroup(groups.getGroupId(), groups.getGroupName(), groups.getGroupHead()));
            }
            // 好友
            List<UserFriendDto> userFriendList = msg.getUserFriendList();
            if (null != userFriendList && userFriendList.size() > 0) {
                userFriendList.forEach(friend -> chat.addFriendUser(false, friend.getFriendId(), friend.getFriendName(), friend.getFriendHead()));
            }
            // 在线好友的P2P地址。更新在线状态的同时加入到P2P组中
            List<ClientAddressDto> friendAddressList = msg.getFriendAddressList();
            if (null != friendAddressList && friendAddressList.size() > 0) {
                friendAddressList.forEach(friendAddr -> {
                    InetSocketAddress friendSocketAddress = new InetSocketAddress(friendAddr.getWantedUserHost(), friendAddr.getWantedUserPort());
                    // 更新P2P组
                    CacheUtil.p2pMap.put(friendAddr.getWantedUserId(), friendSocketAddress);
                    logger.info("保存 {} 好友的UDP打洞地址: {}", friendAddr.getWantedUserId(), friendSocketAddress.toString());
                    chat.changeFriendOnLineStatus(friendAddr.getWantedUserId(), NettyClientConstant.OnLineStatus.OnLine.getCode());
                });
            }
        });
    }
}
